#!/bin/bash

pwd_dir=$(dirname $0)

source $pwd_dir/../config.mk

get_config_info() #定义了一个名为 get_config_info 的函数，用于获取和打印编译配置信息
{
    CHIP_SERIES=$CONFIG_CHIP_SERIES
	CROSS_COMPILE=$CONFIG_CROSS_COMPILE
	chip_series=$(echo $CHIP_SERIES | tr '[A-Z]' '[a-z]') #转换芯片系列名称为小写
    kernel_dir=$CONFIG_OS_DIR/kernel #设置内核目录路径
	kernel_build_dir=$CONFIG_OS_DIR/kbd #内核构建目录
    kernel_install_dir=$CONFIG_TOP_DIR/image #内核安装目录
	driver_install_dir=$CONFIG_TOP_DIR/os/driver #驱动安装目录
    uboot_tools_dir=$CONFIG_TOP_DIR/tools/uboot_tools #u-boot工具目录路径
    num_of_cpu_cores=$(nproc) #获取cpu核心数

	echo "CHIP_SERIES: $CHIP_SERIES, chip_series:$chip_series"
	echo "CROSS_COMPILE : $CROSS_COMPILE"
	echo "driver_install_dir : $driver_install_dir"
}

install_kernel_image()
{
	cd $kernel_dir #切换到内核源代码目录

	# 安装镜像
	echo "Install kernel image!"
	find $kernel_build_dir -name uImage | xargs -i cp {} $kernel_install_dir #复制uimage到$kernel_install_dir

	# 安装dtb文件
	echo "Install dtb file!"
	find $kernel_build_dir -name *.dtb | xargs -i cp {} $kernel_install_dir

    # 安装内核模块
    make modules_install O=$kernel_build_dir INSTALL_MOD_PATH=$driver_install_dir/internal

	find $driver_install_dir/internal -name "build" | xargs rm
	find $driver_install_dir/internal -name "source" | xargs rm

	cd - #cd - 返回进入此函数前的工作目录
}

pack_uImage() #将 RISC-V 架构的 Linux 内核打包为 uImage 格式
{
    kernel_image=$kernel_build_dir/arch/riscv/boot/Image
    if test ! -e $kernel_image ; then
        echo "The Kernel Image $kernel_image is not existed!"
    exit 1
    fi
    echo "kernel_image="$kernel_image

    lzma -f -6 $kernel_image > $kernel_build_dir/arch/riscv/boot/Image.lzma #使用 LZMA 压缩内核镜像
    kernel_image_lzma=$kernel_build_dir/arch/riscv/boot/Image.lzma
    if test ! -e $kernel_image_lzma ; then
        echo "The Kernel Image $kernel_image_lzma is not existed!\n"
    exit 1
    fi
    echo "kernel_image_lzma="$kernel_image_lzma

    #$uboot_tools_dir/mkimage -A riscv -T kernel -C lzma -O linux -a 0x40200000 -e 0x40200000 -n "AnyCloud39AV200 kernel" -d $kernel_image_lzma $kernel_build_dir/arch/riscv/boot/uImage
	$uboot_tools_dir/mkimage -A riscv -T kernel -C lzma -O linux -a 0x40100000 -e 0x40100000 -n "AnyCloud39AV200 kernel" -d $kernel_image_lzma $kernel_build_dir/arch/riscv/boot/uImage
    #使用 mkimage 工具创建 uImage
}

build_kernel() #编译 RISC-V 架构的 Linux 内核
{
    # 检查内核源码目录是否正常
    if test ! -d $kernel_dir ; then
        echo "Build Kernel failed, can't find kernel dir!"
		exit 1
    fi

	pwd
	cd $kernel_dir

    # 创建编译的目标目录
	if test ! -d $kernel_build_dir ; then
    	mkdir $kernel_build_dir
	fi

    # 根据芯片类型进行内核配置
    if [ "$CHIP_SERIES" = "AK3918AV200" ];then
        make O=$kernel_build_dir ARCH=riscv ${chip_series}_mini_defconfig CROSS_COMPILE=$CROSS_COMPILE
    else
        make O=$kernel_build_dir anycloud_${chip_series}_mini_defconfig CROSS_COMPILE=$CROSS_COMPILE
    fi

    # 检查配置是否正常
    if test $? -ne 0 ; then
        exit 1
    fi

    # 编译内核
    if [ "$CHIP_SERIES" = "AK3918AV200" ];then
        make O=$kernel_build_dir ARCH=riscv  -j$num_of_cpu_cores CROSS_COMPILE=$CROSS_COMPILE
        make O=$kernel_build_dir ARCH=riscv dtbs modules -j$num_of_cpu_cores CROSS_COMPILE=$CROSS_COMPILE
    else
        make O=$kernel_build_dir dtbs modules uImage -j$num_of_cpu_cores CROSS_COMPILE=$CROSS_COMPILE 
        #一次性编译设备树、模块和 uImage（通过 pack_uImage() 函数生成的可引导镜像，输出uImage, dtb 文件，内核模块
    fi

    # 检查是否编译出错
    if test $? -ne 0 ; then
        exit 1
    fi

	cd -
}

clean_kernel() 
{
    # 检查编译过程目录是否存在，如果存在先清除掉上一次的编译
    if test -d $kernel_build_dir ; then
		echo "Build kernel dir($kernel_build_dir) , clean it"
        rm -rf $kernel_build_dir
    fi
}

get_config_info

case "$1" in
	all)
        build_kernel #编译内核源码
        if [ "$CHIP_SERIES" = "AK3918AV200" ];then
            pack_uImage
        fi
		install_kernel_image #安装内核镜像，设备树文件和内核模块
		;;
	image)
        build_kernel
		;;
	install)
        install_kernel_image
		;;
	clean)
		clean_kernel
		;;
	*)
		echo "Usage:"
		echo " $0 all   : build kernel and install"
		echo " $0 image   : build kernel"
		echo " $0 install   : install kernel image/dtb/ko"
		echo " $0 clean : clean kernel"
		;;
esac
